﻿using Core.Log;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Core.Utility.Helper
{

    /// <summary>
    /// 正则表达式助手类
    /// </summary>
    public static class RegexHelper
    {
        #region 通配符相关
        /// <summary>
        /// 通配符到正则表达式;
        /// <para>一般用于文件的?和*的通配查找</para>
        /// <para>通配符转正则 处理 ? *</para>
        /// <code>
        /// var rex = WildCardToRegex(@"\data_dll\*.bak");
        /// //list为文件路径列表，返回值为通配列表
        /// var temp = list.Where(ex => Regex.IsMatch(ex, rex, RegexOptions.IgnoreCase)).ToList();
        /// </code>
        /// </summary>
        /// <param name="rex">
        /// 需要通配的表达式,该值不能为null或string.Empty
        /// <para>例如：查找 xxx路径下带有dll扩展名的文件: rex = "\xxx\*.dll" </para>
        /// </param> 
        /// <returns>
        /// 与通配符相关的正则表达式
        /// </returns>
        public static string WildCardToRegex(string rex)
        {
            if (string.IsNullOrEmpty(rex))
            {
                throw new ArgumentNullException(nameof(rex), $"参数不能为null或空字符串");
            }
            return "^" + Regex.Escape(rex).Replace("\\?", ".").Replace("\\*", ".*") + "$";
        }

        /// <summary>
        /// 通配列表
        /// </summary>
        /// <param name="list">通配前的列表</param>
        /// <param name="rex">通配表达式</param>
        /// <param name="regexOptions">表达式选项，参考：<see cref="RegexOptions"/></param>
        /// <returns>通配结果</returns>
        public static List<string> WildCardList(this List<string> list,string rex, RegexOptions regexOptions = RegexOptions.IgnoreCase)
        {
            List<string>? res = new List<string>();            
            try
            {
                var regexString = WildCardToRegex(rex);
                res = list.Where(p=> Regex.IsMatch(p,regexString, regexOptions))?.ToList();
            }
            catch(Exception ex)
            {
                StringBuilder exInfos = new StringBuilder();
                exInfos.AppendLine($"调用通配列表方法失败,入参:");
                exInfos.AppendLine($"list:");
                exInfos.AppendLine($"{JsonHelper.EexceptionSerialize(list)}");
                exInfos.AppendLine($"rex:");
                exInfos.AppendLine($"{rex}");
                AppTrace.Logger.LogWarning(ex, $"{exInfos?.ToString()}");
            }
            if (res == null)
            {
                res = new List<string>();
            }
            return res;
        }
        #endregion
    }
}
